﻿using System.Diagnostics;
using System.Net;
using System.Net.Sockets;

namespace CoHubServerCore.Tcp;

public class TcpServer
{
    private readonly TcpListener _listener;
    private static readonly List<TcpClient> Clients = new();

    public delegate void ClientCycleHandler(TcpClient client, string message);

    public event ClientCycleHandler? ClientCycleEvent;

    public TcpServer(int port)
    {
        var ipEndPoint = new IPEndPoint(IPAddress.Any, port);
        _listener = new TcpListener(ipEndPoint);
    }

    public void Start()
    {
        _listener.Start();
        _listener.BeginAcceptTcpClient(DoAcceptTcpClient, _listener);
    }

    private void DoAcceptTcpClient(IAsyncResult state)
    {
        var listener = (state.AsyncState as TcpListener)!;
        TcpClient client = new(listener.EndAcceptTcpClient(state));
        Clients.Add(client);
        Debug.WriteLine($"收到新客户端:{client.RemoteEndPoint}");
        Thread myThread = new(ClientCycle);
        myThread.Start(client);
        listener.BeginAcceptTcpClient(DoAcceptTcpClient, listener);
    }

    private void ClientCycle(object? clientObj)
    {
        var client = (clientObj as TcpClient)!;
        while (true)
        {
            try
            {
                var message = client.Receive();
                if (message == null) break;
                ClientCycleEvent?.Invoke(client, message);
            }
            catch (Exception e) when(e is InvalidOperationException or IOException)
            {
                break;
            }
        }
    }

    public void Stop()
    {
        Clients.ForEach((client => client.Close()));
        _listener.Stop();
        _listener.Dispose();
    }
}